/**
 * @author Yuqi Chou
 * @version  Jun 1, 2012
 */
package com.threeti.mecool.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.threeti.mecool.core.application.SearchService;
import com.threeti.mecool.core.application.acl.EmployeeService;
import com.threeti.mecool.core.application.basicdata.BasicDataService;
import com.threeti.mecool.core.application.project.ProjectService;
import com.threeti.mecool.core.domain.model.acl.Orgnization;
import com.threeti.mecool.core.domain.model.acl.OrgnizationEmployee;
import com.threeti.mecool.core.domain.model.acl.User;
import com.threeti.mecool.core.domain.model.basicdata.AdminDivision;
import com.threeti.mecool.core.domain.model.basicdata.AdminDivisionLevelDeep;
import com.threeti.mecool.core.domain.model.basicdata.biz.ChannelCategory;
import com.threeti.mecool.core.domain.model.basicdata.biz.ChannelSync;
import com.threeti.mecool.core.domain.model.dto.ChannelSyncDto;
import com.threeti.mecool.core.domain.model.project.ProjectStore;
import com.threeti.mecool.core.infrastructure.persistence.basicdata.biz.ChannelSyncRepository;
import com.threeti.mecool.core.infrastructure.persistence.project.ProjectStoreRepository;
import com.threeti.mecool.framework.util.Lists;
import com.threeti.mecool.framework.util.PageHandler;
import com.threeti.mecool.legacy.domain.model.basicdata.biz.PosKindLegacy;
import com.threeti.mecool.legacy.domain.model.basicdata.biz.PosSysTypeLegacy;
import com.threeti.mecool.legacy.infrastructure.persistence.PosKindLegacyRepository;
import com.threeti.mecool.legacy.infrastructure.persistence.PosSysTypeLegacyRepository;
import com.threeti.mecool.shared.util.AbstractTreeNode;
import com.threeti.mecool.web.assembler.ProjectAssembler;
import com.threeti.mecool.web.util.JsTreeDataUtil;
import com.threeti.mecool.web.util.JsTreeDataUtil.MapTreeNodeDataAssembling;
import com.threeti.mecool.web.util.RequestUtil;

/**
 * @author Yuqi Chou 
 * @version Jun 1, 2012  3:13:12 PM
 */
@Controller
public class BasicDataMainController {
	
	@Autowired
	private BasicDataService basicDataService;
	
	@Autowired
	private EmployeeService empService;
	
	@Autowired
	private ProjectStoreRepository projectStoreRepository;
	
	@Autowired
	private ProjectService projectService;
	
	@Autowired
	private ChannelSyncRepository channelSyncRepo;
	
	@Autowired
	private SearchService searchService;
	
	@Autowired
	private PosKindLegacyRepository posKindLegacyRepository;
	
	@Autowired
	private PosSysTypeLegacyRepository posSysTypeLegacyRepository;
	
	/**
	 * 返回所有通路类型
	 * @author Yuqi Chou
	 * @return
	 * @version Jun 1, 2012  3:18:33 PM
	 */
	@ResponseBody
	@RequestMapping(value = "/json/findAllChannelCategories.html")
	Object findAllChannelCategories(){
		List<ChannelCategory> categories = basicDataService.findAllChannelCategories();
		
		List<Map<String,Object>> treeMap=new ArrayList<Map<String,Object>>();
		
		for (ChannelCategory channelCategory : categories) {
			JsTreeDataUtil.buildTree(channelCategory,treeMap);
		}
		return treeMap;
	}
	
	
	/**
	 * 完整的 组织机构树
	 * @author Yuqi Chou
	 * @return
	 * @version Jun 4, 2012  2:43:57 PM
	 */
	@ResponseBody
	@RequestMapping(value = "/json/findAllOrgnizations.html")
	Object findAllOrgnizations(){
		List<Orgnization> tree = empService.findAllOrgnizations();
		List<Map<String,Object>> treeMap=new ArrayList<Map<String,Object>>();
		for (Orgnization orgnization : tree) {
			JsTreeDataUtil.buildTree(orgnization,treeMap);
		}
		return treeMap;
	}
	
	
	/**
	 * 取得特定机构的所有下级员工树 
	 * @author Yuqi Chou
	 * @param orgCode
	 * @return
	 * @version Jun 4, 2012  2:46:00 PM
	 */
	@ResponseBody
	@RequestMapping(value = "/json/findAllChildEmployeesBy.html")
	Object findAllChildEmployeesBy(@RequestParam(required=true) String orgCode){
		List<OrgnizationEmployee> tree = empService.findAllChildEmployeesBy(orgCode);
		List<Map<String,Object>> treeMap=new ArrayList<Map<String,Object>>();
		for (OrgnizationEmployee orgnizationEmployee : tree) {
			JsTreeDataUtil.buildTree(orgnizationEmployee,treeMap);
		}
		return treeMap;
	}
	
	
	
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(value = "/channelList.html")
	public String findChannels(Map modelMap,
							  @RequestParam(required=false) String projectId,
							  @RequestParam(required=false) String empId){
		
		modelMap.put("posKindList", posKindLegacyRepository.findAll());
		modelMap.put("sysPosKindList", posSysTypeLegacyRepository.findAll());
		
		
		modelMap.put("projectId", projectId);
		modelMap.put("empId",empId);
		
		return "admin/channelList";
	}
			
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping(value = "/channelListData.html")
	public String findChannels(Pageable pageable, Map modelMap,
			@RequestParam(required = false) Long projectId,
			@RequestParam(required = false) Long empId, HttpServletRequest request) {

		List channelsList = Lists.newArrayList();
		Page resultPage = new PageImpl(channelsList);
		if (projectId != null && projectId > 0) {
			if (empId != null && empId > 0) {
				OrgnizationEmployee employee = empService.findByEmployeeId(empId);
				if (employee != null) {
					User user = new User();
					user.setEmployee(employee);
					List<ProjectStore> preAssigned = projectService.findStoresPreAssignedToUserWithinTheProject(user,projectId);
					for (ProjectStore projectStore : preAssigned) {
						channelsList.add(projectStore.getChannel());
					}
				}
			} else {
				resultPage = projectStoreRepository.findAll(
						ProjectAssembler.toCriteria(projectId), pageable);
				List<ProjectStore> stores = resultPage.getContent();
				channelsList = new ArrayList<ChannelSync>();
				for (ProjectStore projectStore : stores) {
					channelsList.add(projectStore.getChannel());
				}
			}
		} else {
//			resultPage = channelSyncRepo.findByType(ChannelSync.TYPE_CONCERNED_ABOUT_GPS, pageable);
			
			resultPage=searchService.findChannelSync(RequestUtil.getParameterMap(request), pageable);
			
			channelsList=resultPage.getContent();
		}

		
		for (int i = 0; i < channelsList.size(); i++) {
			Object obj=channelsList.get(i);
			if(obj instanceof ChannelSync){
				ChannelSyncDto dto=new ChannelSyncDto();
				ChannelSync data = (ChannelSync)obj;
				dto.setId(data.getId());
	            dto.setCode(data.getCode());
	            dto.setName(data.getName());
	            dto.setAdName(data.getAdName());
	            
	            PosKindLegacy pkl = posKindLegacyRepository.findByCode(data.getCategory());
	            if(pkl!=null){
	            	dto.setCategory(pkl.getName());
	            }
	            
	            PosSysTypeLegacy pstl=posSysTypeLegacyRepository.findByCode(data.getSysCategory());
	            if(pstl!=null){
	            	dto.setSysCategory(data.getSysCategory());
	            }
	            
	            dto.setCityAdName(data.getCityAdName());
	            dto.setAddress(data.getAddress());
				channelsList.set(i, dto);
			}
		}
		
		
		modelMap.put("page",
					  new PageHandler(pageable.getPageNumber(),
							  		  Long.valueOf(resultPage.getTotalElements()).intValue(), 
							  		  pageable.getPageSize(),
							  		  channelsList));
		modelMap.put("otherChannels", channelSyncRepo.findByType(ChannelSync.TYPE_NOT_CONCERNED_ABOUT_GPS, pageable).getContent());

		return "/admin/channelListData";
	}
	
	@ResponseBody
	@RequestMapping(value = "/json/findAdminDivisions.html")
	Object findAdminDivisions(@RequestParam(required=false) String adname, 
							  @RequestParam(required=false) final String code,
							  @RequestParam(defaultValue="0") final int depth){
		
		List<Map<String,Object>> treeMap=new ArrayList<Map<String,Object>>();
		List<AdminDivision> tree=Lists.newArrayList();
		if(depth==0){
			tree= basicDataService.findAdminDivisionsByLevelDeep(AdminDivisionLevelDeep.PROVINCE);
		}else if(depth==1){
			tree=  basicDataService.findAdminDivisionsByParentProvinceAdNameAndLevelDeep(adname, code, AdminDivisionLevelDeep.CITY);
		}else if(depth==2){
			tree=  basicDataService.findAdminDivisionsByParentCityAdNameAndAdCode(adname, code);
		}
		if(tree.size()>0){
			MapTreeNodeDataAssembling treeNodeDataAssembling=new MapTreeNodeDataAssembling() {
				@SuppressWarnings("rawtypes")
				public Map assembling(AbstractTreeNode entryNode) {
					Map<String, Object> jsonData = new HashMap<String, Object>();
					AdminDivision adminDivision=(AdminDivision) entryNode;
					if(adminDivision.getId().toString().equals(code)){
						return null;
					}
		  			jsonData.put("name", adminDivision.getName());
		  			jsonData.put("code", adminDivision.getId());
		  			jsonData.put("id",adminDivision.getId());
		  			if(depth<2){
		  				jsonData.put("depth", depth+1);
		  	  			jsonData.put("isParent", true);
		  			}
					return jsonData;
				}
			};
			for (AdminDivision topLevelNode : tree) {
				JsTreeDataUtil.buildTree(topLevelNode, treeMap,treeNodeDataAssembling);
			}
		}
		
		
		return treeMap;
	}
	
	
	
	
}
